package com.leven.printer.sdk.manager.usb;

import android.annotation.SuppressLint;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.util.Log;

import com.alibaba.fastjson.JSONObject;
import com.leven.printer.sdk.listener.PrinterListener;
import com.leven.printer.sdk.listener.UsbPrinterListener;
import com.leven.printer.sdk.manager.PrinterManager;
import com.printer.sdk.PrinterInstance;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * usb打印类
 */
public class UsbPrinterManager extends PrinterManager {
    @SuppressLint("StaticFieldLeak")
    private static UsbPrinterManager instance;
    private final Context context;
    private final UsbManager usbManager;
    private UsbPrinterListener listener;
    private static final String ACTION_USB_PERMISSION = "com.android.usb.USB_PERMISSION";
    private UsbDevice mUSBDevice;

    public UsbPrinterManager(Context context){
        this.context = context;
        usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
    }

    public static UsbPrinterManager getInstance(Context context) {
        if(instance == null){
            instance = new UsbPrinterManager(context);
        }
        return instance;
    }

    /**
     * 获取所有usb设备
     */
    public List<JSONObject> getAllUsbDevices() {
        HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
        List<JSONObject> list = new ArrayList<>();
        if (!deviceList.isEmpty()) {
            for (UsbDevice device : deviceList.values()) {
                list.add(getUsbDeviceData(device));
            }
        }
        return list;
    }

    /**
     * 获取所有打印机设备
     */
    public List<JSONObject> getAllUsbPrinterDevices(){
        HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
        List<JSONObject> list = new ArrayList<>();
        if (!deviceList.isEmpty()) {
            for (UsbDevice device : deviceList.values()) {
                if(isUsbPrinter(device)){
                    list.add(getUsbDeviceData(device));
                }
            }
        }
        return list;
    }

    /**
     * 连接usb设备
     */
    public void connect(String deviceName, UsbPrinterListener listener) {
        this.listener = listener;
        //获取设备信息
        mUSBDevice = getUsbDeviceByDeviceName(deviceName);
        if (mUSBDevice == null) {
            if (listener != null) {
                listener.onNoDevice();
            }
        } else {
            //设置回调数据
            setParentPrinterListener();
            myPrinter = PrinterInstance.getPrinterInstance(context, mUSBDevice, handler);
            //注册服务
            registerReceiver();
            //找到设备，判断是否有权限
            if (usbManager.hasPermission(mUSBDevice)) {
                //有权限直接连接
                myPrinter.openConnection();
            } else {
                PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
                usbManager.requestPermission(mUSBDevice, pendingIntent); // 该代码执行后，系统弹出一个对话框
            }
        }
    }

    /**
     * 注册usb
     */
    private void registerReceiver() {
        IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
        filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
        context.registerReceiver(mUsbReceiver, filter);
    }

    /**
     * 根据设备名称获取设备
     */
    private UsbDevice getUsbDeviceByDeviceName(String deviceName) {
        HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
        if (deviceList.isEmpty()) {
            return null;
        }
        for (UsbDevice device : deviceList.values()) {
            if (device.getDeviceName().equals(deviceName)) {
                return device;
            }
        }

        return null;
    }

    /**
     * 获取usb数据
     */
    private JSONObject getUsbDeviceData(UsbDevice device) {
        if(device == null){
            return null;
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("deviceName", device.getDeviceName());
        jsonObject.put("deviceId", device.getDeviceId());
        jsonObject.put("productId", device.getProductId());
        jsonObject.put("productName", device.getProductName());
        jsonObject.put("vendorId", device.getVendorId());
        jsonObject.put("deviceClass", device.getDeviceClass());
        return jsonObject;
    }

    /**
     * 是否是打印机设备
     * @param device
     * @return
     */
    private boolean isUsbPrinter(UsbDevice device) {
        if(device == null){
            return false;
        }
        UsbInterface usbInterface = device.getInterface(0);
        return usbInterface.getInterfaceClass() == 7;
    }

    /**
     * 设置连接回调
     */
    private void setParentPrinterListener(){
        setPrinterListener(new PrinterListener() {
            @Override
            public void onConnected() {
                if(listener != null){
                    listener.onConnected(myPrinter, getUsbDeviceData(mUSBDevice));
                }
            }

            @Override
            public void onFailed() {
                if(listener != null){
                    listener.onFailed(getUsbDeviceData(mUSBDevice));
                }
            }

            @Override
            public void onNoDevice() {
                if(listener != null){
                    listener.onNoDevice();
                }
            }

            @Override
            public void onClose() {
                if(listener != null){
                    listener.onClose(getUsbDeviceData(mUSBDevice));
                }
            }

            @Override
            public void onUnknownError() {
                if(listener != null){
                    listener.onUnknownError();
                }
            }
        });
    }

    private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
        @SuppressLint("NewApi")
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
            if (ACTION_USB_PERMISSION.equals(action)) {
                synchronized (this) {
                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)
                            && mUSBDevice.equals(device)) {
                        if(myPrinter != null){
                            myPrinter.openConnection();
                        }else if(listener != null){
                            listener.onUnknownError();
                        }
                    } else {
                        if (listener != null) {
                            listener.onFailed(getUsbDeviceData(device));
                        }
                    }
                }
            } else if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
                //usb插入
                if (listener != null) {
                    listener.onAttached(getUsbDeviceData(device));
                }
            } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
                //usb拔掉
                if (listener != null) {
                    listener.onDetached(getUsbDeviceData(device));
                }
            }
        }
    };
}
